﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using ACL.Comm;
using System.Web;
using System.IO;

namespace ACL.P2P
{   
    [ServiceBehavior(InstanceContextMode= InstanceContextMode.PerCall)]

    public class P2PService : IPeerToPeer
    {



        string uploadFolder = @"C:\upload\";
        string downloadFolder = @"C:\upload\readyForDownload\";

        public RemoteFileInfo GetFile(DownloadRequest request)
        {
            RemoteFileInfo result = new RemoteFileInfo();
            try
            {
                string filePath = System.IO.Path.Combine(downloadFolder, request.FileName);
                System.IO.FileInfo fileInfo = new System.IO.FileInfo(filePath);

                // check if exists
                if (!fileInfo.Exists)
                    throw new System.IO.FileNotFoundException("File not found",
                                                              request.FileName);

                // open stream
                System.IO.FileStream stream = new System.IO.FileStream(filePath,
                          System.IO.FileMode.Open, System.IO.FileAccess.Read);

                // return result 
                result.FileName = request.FileName;
                result.Length = fileInfo.Length;
                result.FileByteStream = stream;
            }
            catch (Exception ex)
            {

            }
            return result; 
        }


        public void PutFile(RemoteFileInfo request)
        {
            FileStream targetStream = null;
            Stream sourceStream = request.FileByteStream;

            

            string filePath = Path.Combine(uploadFolder, request.FileName);

            using (targetStream = new FileStream(filePath, FileMode.Create,
                                  FileAccess.Write, FileShare.None))
            {
                //read from the input stream in 65000 byte chunks

                const int bufferLen = 65000;
                byte[] buffer = new byte[bufferLen];
                int count = 0;
                while ((count = sourceStream.Read(buffer, 0, bufferLen)) > 0)
                {
                    // save to output stream
                    targetStream.Write(buffer, 0, count);
                }
                targetStream.Close();
                sourceStream.Close();
            }

            SplitFile(filePath, @"C:\upload\readyForDownload");
        }


        public List<DownloadRequest> RequestFileInfos()
        {
            List<DownloadRequest> files = new List<DownloadRequest>();

            foreach (var file in Directory.GetFiles(uploadFolder))
            {

                files.Add(new DownloadRequest { FileName =  file });
            }

            return files;
        }

        public void Merge(string outputName, string inputPath)
        {
           
            int x = 10;        
            
            

            {
                FileStream outFile = new FileStream(outputName, FileMode.OpenOrCreate, FileAccess.Write);

                for (int i = 0; i < x; i++)
                {
                    int data = 0;
                    byte[] buffer = new byte[1024];
                    FileStream inFile = new FileStream(inputPath + "\\" + i + ".sg", FileMode.OpenOrCreate, FileAccess.Read);
                    while ((data = inFile.Read(buffer, 0, 1024)) > 0)
                    {
                        outFile.Write(buffer, 0, data);
                    }
                    inFile.Close();
                }
                outFile.Close();

            }

        }

        private void SplitFile(string file, string outputPath)
        {
            int eachSize = 0;
            long len = 0;
            int numberoffiles = 10;

            FileInfo fi = new FileInfo(file);

                using (FileStream fileStream = File.OpenRead(file))
                {
                    len = fileStream.Length;
                }

                eachSize = (int)Math.Ceiling((double)len / numberoffiles);

        

            FileStream inFile = new FileStream(file, FileMode.OpenOrCreate, FileAccess.Read);

            for (int i = 0; i < numberoffiles; i++)
            {
                FileStream outFile = new FileStream(outputPath + "\\" + fi.Name + i + ".sg", FileMode.OpenOrCreate, FileAccess.Write);
                int data = 0;

                byte[] buffer = new byte[eachSize];
                if ((data = inFile.Read(buffer, 0, eachSize)) > 0)
                {
                    outFile.Write(buffer, 0, data);
                }
                outFile.Close();
            }
            inFile.Close();

           
        }
    }
}
